﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SilverlightApplication1;
using Microsoft.Silverlight.Testing;
using System.Windows.Threading;
using System.Threading;
using System.Linq;
using LINQAmazonProvider;

namespace Test1
{
    [TestClass]
    public class Test_Class:SilverlightTest
    {
        private Dispatcher _mainDispatcher;
        public IQueryable<Common.DataTypes.Book> Query { get; set; }
        public List<Common.DataTypes.Book> Result { get; set; }

        [TestInitialize]
        public void PreparePage()
        {
            this._mainDispatcher = MainDispatcher.Current;
        }
//------------------------------------------------------------------------------
        /*SELECT/WHERE*/
        #region SELECT/WHERE
        /// <summary>
        /// Harry Potter, not empty result
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SW1()
        {
            bool dataReady = false;
            this.SearchFinished += (s, e) =>
                {
                    dataReady = true;
                };

            string searchKeyword = "Harry Potter";
 
            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                  book.Title == searchKeyword
                select book;
            
            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(()=>dataReady);
            EnqueueCallback(() => Assert.IsTrue(Result.Count > 0));
            
            EnqueueTestComplete();
        }
        
        /// <summary>
        /// Robot, All results having the text "Robot"
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SW2()
        {
            bool dataReady = false;
            
            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchKeyword = "Robot";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                  book.Title == searchKeyword
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchKeyword in result's title
                    t = t && b.Title.Contains(searchKeyword);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------
        
        /// <summary>
        /// in: Title = "Lord of the Rings"
        /// out: Not empty result
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SW1_1()
        {
            bool dataReady = false;
            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "Lord of the Rings";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                  book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);
            EnqueueCallback(() => Assert.IsTrue(Result.Count > 0));

            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "Harry Potter"
        /// out: Every result contains the string "Harry Potter" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SW2_1()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "Harry Potter";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                  book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "América"
        /// out: Every result contains the string "América" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWT1()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "América";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "Open Offise"
        /// out: Every result contains the string "Open Offise" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWTFO1()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "Open Offise";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "Mr/Miss Naugthy"
        /// out: Every result contains the string "Mr/Miss Naugthy" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE1()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "Mr/Miss Naugthy";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "PS: I love you"
        /// out: Every result contains the string "PS: I love you" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE2()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "PS: I love you";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "1+2=3"
        /// out: Every result contains the string "1+2=3" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE3()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "1+2=3";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "Where are you Now?"
        /// out: Every result contains the string "Where are you Now?" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE4()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "Where are you Now?";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "100%HC"
        /// out: Every result contains the string "100%HC" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE5()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "100%HC";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "you&me"
        /// out: Every result contains the string "you&me" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE6()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "you&me";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "flirt m@il"
        /// out: Every result contains the string "flirt m@il" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE7()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "flirt m@il";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "Rule # 1"
        /// out: Every result contains the string "Rule # 1" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE8()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "Rule # 1";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
        //-------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------
        /// <summary>
        /// in: Title = "Make ea$y money!"
        /// out: Every result contains the string "Make ea$y money!" in his Title
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void SWCE9()
        {
            bool dataReady = false;

            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchString = "Make ea$y money!";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);

            Query =
                from book in queryable
                where
                    book.Title == searchString
                select book;

            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);

            bool t = true;
            EnqueueCallback(() =>
            {

                foreach (Common.DataTypes.Book b in Result)
                {
                    // checking for searchString in result's title
                    t = t && b.Title.Contains(searchString);
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));


            EnqueueTestComplete();
        }
       
        #endregion
//------------------------------------------------------------------------------
        /*ORDER BY*/
        
        #region ORDERBY
        /// <summary>
        /// Get a list of books ordered ascendig by title and verify for 
        /// all items that ai<ai+1
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void OB1()
        
        {
            bool dataReady = false;
            this.SearchFinished += (s, e) =>
            {
                dataReady = true; //atach to the event that the data has already arrive
            };

            string searchKeyword = "Harry%20Potter";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);
            bool t = true;

            //Query writed in LinQ
            var query = from book in queryable
                    where
                      book.Keywords == searchKeyword
                    orderby book.Title

                    select book;//from book in queryable
                    //where book.Keywords == searchKeyword
                    //orderby book.Title
                    //select book;
            //result = query.ToList<Book>();
            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);//utill dataredy is true
            int i = 0;

            EnqueueCallback(() =>
            {
                String[] titles = new String[Result.Count]; // string array

                foreach (Common.DataTypes.Book b in Result)// fill it with titles sorted as it is returned
                {
                    titles[i] = b.Title;
                    i++;
                };

                int j = 0;
                while (( j < i - 1) && t)
                {
                    t = String.Compare(titles[j], titles[j + 1]) <= 0;
                    j++;
                }

            });

            EnqueueCallback(() => Assert.IsTrue(t));

            EnqueueTestComplete();
        }

        /// <summary>
        /// 
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void OB2()
        {
            bool dataReady = false;
            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchKeyword = "Harry Potter";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);
            bool t = true;

            Query = from book in queryable
                    where book.Keywords == searchKeyword
                    orderby book.Title ascending, book.ListPrice descending
                    select book;



            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);
            int i = 0;

            EnqueueCallback(() =>
            {
                String[] auth = new String[Result.Count]; 

                foreach (Common.DataTypes.Book b in Result)
                {
                    auth[i] = b.Title; 
                    i++;
                };

                int j = 0;
                while ((j < i - 1) && t)
                {
                    t = String.Compare(auth[j], auth[j + 1]) <= 0;
                    j++;
                }

            });

            EnqueueCallback(() => Assert.IsTrue(t));

            EnqueueTestComplete();
        }

        /// <summary>
        /// 
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void OB3()
        {
            bool dataReady = false;
           this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchKeyword = "Harry Potter";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);
            bool t = true;

            Query = from book in queryable
                    where book.Keywords == searchKeyword
                    orderby book.ListPrice.Amount
                    select book;




            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);
            int i = 0;

            EnqueueCallback(() =>
            {
                int[] prices = new int[Result.Count];

                foreach (Common.DataTypes.Book b in Result)
                {
                    prices[i] = b.ListPrice.Amount;
                    i++;
                };

                int j = 0;
                while ((j < i - 1) && t)
                {
                    t = prices[j] <= prices[j + 1];
                    j++;
                }
            });

            EnqueueCallback(() => Assert.IsTrue(t));

            EnqueueTestComplete();
        }

        /// <summary>
        /// 
        /// </summary>
        [TestMethod]
        [Asynchronous]
        public void OB4()
        {
            bool dataReady = false;
            this.SearchFinished += (s, e) =>
            {
                dataReady = true;
            };

            string searchKeyword = "Harry Potter";

            List<Common.DataTypes.Book> result = new List<Common.DataTypes.Book>();

            var provider = new AmazonProvider();

            var queryable = new AmazonQuery<Common.DataTypes.Book>(provider);
            bool t = true;

            Query = from book in queryable
                    where book.Keywords == searchKeyword
                    orderby book.ListPrice.Amount
                    select book;




            EnqueueCallback(() => GetLinqWorker<Common.DataTypes.Book>().Start());
            EnqueueConditional(() => dataReady);
            int i = 0;

            EnqueueCallback(() =>
            {
                int[] prices = new int[Result.Count];

                foreach (Common.DataTypes.Book b in Result)
                {
                    prices[i] = b.ListPrice.Amount;
                    i++;
                };

                int j = 0;
                while ((j < i - 1) && t)
                {
                    t = prices[j] <= prices[j + 1];
                    j++;
                } 
            });

            EnqueueCallback(() => Assert.IsTrue(t));

            EnqueueTestComplete();
        }
        #endregion
       
        #region helpers
        Thread GetLinqWorker<T>()
        {
            return new Thread(new ThreadStart(GetLINQResult));
        }

        private void GetLINQResult()
        { 
            Result = Query.ToList<Common.DataTypes.Book>();

            _mainDispatcher.BeginInvoke(delegate()
            {
                //OnSearchCompleted(new SearchCompletedEventArgs(result));
                //TODO::Arreglar problema de tipos que retorna y aarreglar
                //SearchCompleted(Query.ToList<T>());
                OnSearchFinished(new SearchFinishedEventArgs());
            });
        }

        public delegate void SearchFinishedHandler(object sender, SearchFinishedEventArgs e);

        public event SearchFinishedHandler SearchFinished;

        protected virtual void OnSearchFinished(SearchFinishedEventArgs e)
        {
            if (SearchFinished != null)
                SearchFinished(this, e);
        }

        #endregion
    }

    public class SearchFinishedEventArgs
    {
        //IEnumerable<T> _result;

        public SearchFinishedEventArgs()//(IEnumerable<T> result)
        {
            //_result = result;
        }

       
    }

    //add this Test to proy Web
}
